home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / diskutil / fdf.zoo / fdfcomm.c < prev    next >
C/C++ Source or Header  |  1992-04-12  |  11KB  |  502 lines

  1. /*
  2.  * fdfcomm.c
  3.  *
  4.  * common functions for find duplicates program
  5.  *
  6.  * Roy Bixler
  7.  * March 23, 1991
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 1, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24.  
  25.  
  26. #include <ctype.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <stdio.h>
  30. #include <osbind.h>
  31. #include <types.h>    /* must be included before stat.h */
  32. #include <stat.h>
  33. #include <unistd.h>
  34.  
  35. #include "cmp.h"
  36. #include "fdfcomm.h"
  37. #include "elib.h"
  38.  
  39.  
  40.  
  41. FILE_LIST *F_list = NULL, *I_del_menu[N_INTERACTIVE];
  42. char Match_criteria = 0, Sort_criteria = 0, Sort_order = ASCENDING;
  43. char i_flag = 0;    /* interactive delete mode */
  44. char l_flag = 0;    /* long listing? */
  45. char v_flag = 0;    /* verbose? */
  46. static char Sorted;
  47.  
  48.  
  49.  
  50. /*
  51.  * print_fdate
  52.  *
  53.  * given a dta structure, print out the date in it
  54.  */
  55. void print_fdate(struct _dta *dta)
  56.  
  57. {
  58.     printf("%02d/%02d/%02d",
  59.            (dta->dta_date >> 9) + 80,
  60.            (dta->dta_date >> 5) & 0xf,
  61.            (dta->dta_date) & 0x1f);
  62. }
  63.  
  64.  
  65.  
  66. /*
  67.  * print_ftime
  68.  *
  69.  * given a dta structure, print out the time in it
  70.  */
  71. void print_ftime(struct _dta *dta)
  72.  
  73. {
  74.     printf("%02d:%02d:%02d",
  75.            (dta->dta_time >> 11),
  76.            (dta->dta_time >> 5) & 0x3f,
  77.            (dta->dta_time & 0x1f));
  78. }
  79.  
  80.  
  81.  
  82. /*
  83.  * print_fdatetime
  84.  *
  85.  * print the given dta's date, a space and the dta's time
  86.  */
  87. void print_fdatetime(struct _dta *dta)
  88.  
  89. {
  90.     print_fdate(dta);
  91.     printf(" ");
  92.     print_ftime(dta);
  93. }
  94.  
  95.  
  96.  
  97. /*
  98.  * print_fpath
  99.  *
  100.  * given a path and a dta, print the path with the dta's name tacked on the
  101.  * end
  102.  */
  103. void print_fpath(char *path, char *f_name)
  104.  
  105. {
  106.     static char *dir_sep = PATH_SEPARATOR;
  107.     int path_len;
  108.  
  109.     if (path != NULL) {
  110.         path_len = strlen(path);
  111.         printf("%s%s%s", path,
  112.                ((path_len > 0) && (path[path_len-1] == dir_sep[0]))
  113.                 ? ""
  114.                 : PATH_SEPARATOR,
  115.                f_name);
  116.     }
  117. }
  118.  
  119.  
  120.  
  121. /*
  122.  * long_listing
  123.  *
  124.  * print out the complete information on the given file
  125.  */
  126. void long_listing(char *path, struct _dta *dta)
  127.  
  128. {
  129.     if (path != NULL) {
  130.         printf("%c ", (dta->dta_attribute == 0x10) ? 'd' : '-');
  131.         print_fdatetime(dta);
  132.         printf(" %8ld ", dta->dta_size);
  133.         print_fpath(path, dta->dta_name);
  134.         printf("\n");
  135.     }
  136. }
  137.  
  138.  
  139.  
  140. /*
  141.  * print_match_header
  142.  *
  143.  * prints the first match of files
  144.  */
  145. void print_match_header(FILE_LIST *start)
  146.  
  147. {
  148.     if (l_flag)
  149.         return;    /* no header */
  150.     else if (Match_criteria & NAMES_MATCH)
  151.         printf("file %s found in directories:\n", start->dta.dta_name);
  152.     else if (Match_criteria & CONTENTS_MATCH)
  153.         printf("files with matching contents (size = %ld) found:\n",
  154.                start->dta.dta_size);
  155.     else if (Match_criteria & SIZES_MATCH)
  156.         printf("files of length %ld found:\n", start->dta.dta_size);
  157.     else if (Match_criteria & TIMES_MATCH) {
  158.         printf("files with timestamp ");
  159.         print_fdatetime(&start->dta);
  160.         printf(" found:\n");
  161.     }
  162. }
  163.  
  164.  
  165.  
  166. /*
  167.  * print_next_match
  168.  *
  169.  * prints out any matches after the first one
  170.  */
  171. void print_next_match(FILE_LIST *next, int menu_num)
  172.  
  173. {
  174.     if (menu_num >= 0)
  175.         printf("%d)%s", menu_num, (l_flag) ? " " : "");
  176.     if (l_flag)
  177.         long_listing(next->path, &next->dta);
  178.     else if (Match_criteria & NAMES_MATCH)
  179.         printf("\t%s\n", next->path);
  180.     else {
  181.         printf("\t"); print_fpath(next->path, next->dta.dta_name);
  182.         printf("\n");
  183.     }
  184.  
  185.     next->printed = 1;
  186. }
  187.  
  188.  
  189.  
  190. /*
  191.  * print_id_menu
  192.  *
  193.  * given a starting point in the file list, print out an interactive delete
  194.  * menu.
  195.  */
  196. void print_id_menu(FILE_LIST **menu, int num_items)
  197.  
  198. {
  199.     int i;
  200.  
  201.     print_match_header(menu[0]);
  202.     for (i = 0; i < num_items; i++)
  203.         print_next_match(menu[i], i+1);
  204. }
  205.  
  206.  
  207.  
  208. /*
  209.  * cmpflist
  210.  *
  211.  * returns non-zero if the FILE_LIST parameter is less/greater than the given
  212.  * dta/path combination according to the sort criteria.  If sort
  213.  * order is ASCENDING,  non-zero returned if FILE_LIST less than dta/path
  214.  * combo, vice-versa for DESCENDING order.
  215.  */
  216. int cmpflist(FILE_LIST *fd, char *path, struct _dta *dta)
  217.  
  218. {
  219.     long cmptime_tmp;
  220.     int tmp;
  221.  
  222.     switch (Sort_criteria) {
  223.     case NAME_SORT:
  224.         return (Sort_order == ASCENDING)
  225.                     ? (((tmp = strcmp(fd->dta.dta_name, dta->dta_name)) < 0) ||
  226.                        ((tmp == 0) && (strcmp(fd->path, path) <= 0)))
  227.                     : (((tmp = strcmp(fd->dta.dta_name, dta->dta_name)) > 0) ||
  228.                        ((tmp == 0) && (strcmp(fd->path, path) >= 0)));
  229.     case SIZE_SORT:
  230.         return (Sort_order == ASCENDING)
  231.                     ? ((fd->dta.dta_size < dta->dta_size) ||
  232.                        ((fd->dta.dta_size == dta->dta_size) &&
  233.                         (strcmp(fd->dta.dta_name, dta->dta_name) < 0)) ||
  234.                        ((fd->dta.dta_size == dta->dta_size) &&
  235.                         (strcmp(fd->path, path) <= 0)))
  236.                     : ((fd->dta.dta_size > dta->dta_size) ||
  237.                        ((fd->dta.dta_size == dta->dta_size) &&
  238.                         (strcmp(fd->dta.dta_name, dta->dta_name) > 0)) ||
  239.                        ((fd->dta.dta_size == dta->dta_size) &&
  240.                         (strcmp(fd->path, path) >= 0)));
  241.     case TIME_SORT:
  242.         return (Sort_order == ASCENDING)
  243.                     ? (((cmptime_tmp = cmptime(&fd->dta, dta)) < 0) ||
  244.                        ((cmptime_tmp == 0) &&
  245.                         ((tmp = strcmp(fd->dta.dta_name,
  246.                                        dta->dta_name)) < 0)) ||
  247.                         ((tmp == 0) && (strcmp(fd->path, path) <= 0)))
  248.                     : (((cmptime_tmp = cmptime(&fd->dta, dta)) > 0) ||
  249.                        ((cmptime_tmp == 0) &&
  250.                         ((tmp = strcmp(fd->dta.dta_name,
  251.                                        dta->dta_name)) > 0)) ||
  252.                         ((tmp == 0) && (strcmp(fd->path, path) >= 0)));
  253.     default:
  254.         return 0;    /* unknown sort criteria */
  255.     }
  256. }
  257.  
  258.  
  259.  
  260. /*
  261.  * cmpflist_eq
  262.  *
  263.  * returns non-zero if the two FILE_LIST parameters are equal according to the
  264.  * sort criteria.
  265.  */
  266. int cmpflist_eq(FILE_LIST *fd1, FILE_LIST *fd2)
  267.  
  268. {
  269.     if (fd1 == NULL)
  270.         return (fd2 == NULL);
  271.     else if (fd2 == NULL)
  272.         return 0;
  273.     switch (Sort_criteria) {
  274.     case NAME_SORT:
  275.         return !strcmp(fd1->dta.dta_name, fd2->dta.dta_name);
  276.     case SIZE_SORT:
  277.         return (fd1->dta.dta_size == fd2->dta.dta_size);
  278.     case TIME_SORT:
  279.         return !cmptime(&fd1->dta, &fd2->dta);
  280.     default:
  281.         return 0;    /* unknown sort criteria */
  282.     }
  283. }
  284.  
  285.  
  286.  
  287. /*
  288.  * files_match
  289.  *
  290.  * return non-zero if the given two files 'match' according to names and the
  291.  * criteria set by the flags (contents, date/time, size or almost any
  292.  * combination of these).
  293.  */
  294. int files_match(FILE_LIST *file1, FILE_LIST *file2)
  295.  
  296. {
  297.     return (((!(Match_criteria & NAMES_MATCH)) ||
  298.              (!strcmp(file1->dta.dta_name, file2->dta.dta_name))) &&
  299.             ((!(Match_criteria & SIZES_MATCH)) ||
  300.              (file1->dta.dta_size == file2->dta.dta_size)) &&
  301.             ((!(Match_criteria & TIMES_MATCH)) ||
  302.              (!cmptime(&file1->dta, &file2->dta))) &&
  303.             ((!(Match_criteria & CONTENTS_MATCH)) ||
  304.              (compare_path_name_files(file1->path, file1->dta.dta_name,
  305.                                        file2->path, file2->dta.dta_name))));
  306. }
  307.  
  308.  
  309.  
  310. /*
  311.  * gen_list
  312.  *
  313.  * given a path, generate a list of all files in the path and its
  314.  * subdirectories.
  315.  */
  316. void gen_list(char *path)
  317.  
  318. {
  319.     struct _dta *odta, dta;
  320.     char *path_list, *save_path;
  321.  
  322.     odta = (struct _dta *) Fgetdta();
  323.     Fsetdta(&dta);
  324.  
  325.     if (path == NULL)
  326.         return;
  327.     path_list = append_dir_to_path(path, ADD_TO_PATH);
  328.     if ((Fsfirst(path_list, -1) >= 0) &&
  329.         ((save_path = malloc((size_t) (strlen(path)+1))) != NULL)) {
  330.         strcpy(save_path, path);
  331.         do {
  332.             if (dta.dta_attribute & FA_DIR)
  333.                 gen_list_of_dir(path, dta.dta_name);
  334.             else
  335.                 add_file_to_list(save_path, &dta);
  336.         } while (!Fsnext());
  337.     }
  338.  
  339.     free(path_list);
  340.     Fsetdta(odta);
  341. }
  342.  
  343.  
  344.  
  345. /*
  346.  * add_file_to_list
  347.  *
  348.  * given a path and a file on the path, add it to the list according to the
  349.  * sort criteria.
  350.  */
  351. void add_file_to_list(char *path, struct _dta *dta)
  352.  
  353. {
  354.     FILE_LIST *prev = NULL, *new, *cur = F_list;
  355.  
  356.     if (Sorted)
  357.         while ((cur != NULL) && (cmpflist(cur, path, dta))) {
  358.             prev = cur;
  359.             cur = cur->next;
  360.         }
  361.  
  362.     if ((new = malloc((size_t) sizeof(FILE_LIST))) == NULL) {
  363.         printf("add_file_to_list: memory allocation failure\n");
  364.         exit(-1);
  365.     }
  366.     else {
  367.         memcpy(&new->dta, d